package com.sc.nft.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.sc.nft.dao.*;
import com.sc.nft.dto.EcologyPoolIncreasePointsDTO;
import com.sc.nft.dto.UserEcologyHatchRecordsDao;
import com.sc.nft.entity.*;
import com.sc.nft.enums.*;
import com.sc.nft.service.EcologyPoolCommunityServiceRankConfService;
import com.sc.nft.service.EcologyPoolService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author PC
 * @description 针对表【sc_ecology_pool_community_service_rank_conf(生态池-服务中心/社区网点榜单配置)】的数据库操作Service实现
 * @createDate 2024-07-22 13:48:10
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class EcologyPoolCommunityServiceRankConfServiceImpl implements EcologyPoolCommunityServiceRankConfService {
    private final EcologyPoolCommunityServiceRankConfDao ecologyPoolCommunityServiceRankConfDao;
    private final UserWorkRoomDao userWorkRoomDao;
    private final UserCityServerCentreDao userCityServerCentreDao;
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;
    private final EcologyPoolCommunityServiceRankIncomeConfDao ecologyPoolCommunityServiceRankIncomeConfDao;
    private final EcologyPoolPrizeDao ecologyPoolPrizeDao;
    private final EcologyPoolCommunityServiceRankDao ecologyPoolCommunityServiceRankDao;
    private final EcologyPoolService ecologyPoolService;
    private final EcologyPoolRelationConditionBindDao ecologyPoolRelationConditionBindDao;

    /**
     * 获取要排行的活动列表
     *
     * @return
     */
    @Override
    public List<EcologyPoolCommunityServiceRankConf> getActiveRankings() {
        return ecologyPoolCommunityServiceRankConfDao.getActiveRankings();
    }

    @Override
    public List<EcologyPoolCommunityServiceRank> excellentBrandRanking(EcologyPoolCommunityServiceRankConf ecologyPoolCommunityServiceRankConf) {
        //关联藏品
        List<EcologyPoolRelationConditionBind> bindList = ecologyPoolRelationConditionBindDao.getListByBind(ecologyPoolCommunityServiceRankConf.getId(), EcologyPoolRelationConditionBindTypeEnum.COMMUNITY_SERVICE_CENTER_RANK, EcologyPoolRelationTypeEnum.COLLECTION);
        List<Long> collectionIdList = CollectionUtil.isNotEmpty(bindList) ? bindList.stream().map(EcologyPoolRelationConditionBind::getRelationId).distinct().collect(Collectors.toList()) : Collections.emptyList();
        List<EcologyPoolCommunityServiceRank> list = new ArrayList<>();
        // 不同的榜单有不同的计算规则
        if (ecologyPoolCommunityServiceRankConf.getRankType() == EcologyPoolCommunityServiceRankTypeEnum.COMMUNITY) {
            community(list, ecologyPoolCommunityServiceRankConf, collectionIdList);
        }
        if (ecologyPoolCommunityServiceRankConf.getRankType() == EcologyPoolCommunityServiceRankTypeEnum.SERVICE_CENTER) {
            serviceCenter(list, ecologyPoolCommunityServiceRankConf, collectionIdList);
        }
        return list;
    }

    @Override
    public List<EcologyPoolCommunityServiceRankConf> getWaitAutoSettleRankings() {
        return ecologyPoolCommunityServiceRankConfDao.getWaitAutoSettleRankings();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void autoSettle(EcologyPoolCommunityServiceRankConf ecologyPoolCommunityServiceRankConf) {
        //自动结算且未结算
        if (!ecologyPoolCommunityServiceRankConf.getAutoSettle()
                || ecologyPoolCommunityServiceRankConf.getSettled()) {
            return;
        }
        //收益
        List<EcologyPoolCommunityServiceRankIncomeConf> ecologyPoolCommunityServiceRankIncomeConfList = ecologyPoolCommunityServiceRankIncomeConfDao.getListByConfId(ecologyPoolCommunityServiceRankConf.getId());
        if (CollUtil.isEmpty(ecologyPoolCommunityServiceRankIncomeConfList)) {
            return;
        }
        List<Long> incomeIdList = ecologyPoolCommunityServiceRankIncomeConfList.stream().map(EcologyPoolCommunityServiceRankIncomeConf::getId).collect(Collectors.toList());
        //收益奖励
        List<EcologyPoolPrize> ecologyPoolPrizeList = ecologyPoolPrizeDao.listPrizeById(incomeIdList, EcologyPoolPrizeBindTypeEnum.COMMUNITY_SERVICE_CENTER_RANK_INCOME, EcologyPoolLinkTypeEnum.POINTS);
        if (CollUtil.isEmpty(ecologyPoolPrizeList)) {
            return;
        }

        //排行榜最后一天日期
        EcologyPoolCommunityServiceRank maxRankDate = ecologyPoolCommunityServiceRankDao.getMaxRankDate(ecologyPoolCommunityServiceRankConf.getId());
        if (Objects.isNull(maxRankDate)) {
            return;
        }

        //排行榜最后一天日期是否配置的最后一天日期
        Date rankDate = DateUtil.truncate(DateUtil.beginOfDay(maxRankDate.getRankDate()), DateField.SECOND);
        Date endTime = DateUtil.truncate(DateUtil.beginOfDay(ecologyPoolCommunityServiceRankConf.getEndTime()), DateField.SECOND);
        if (!Objects.equals(rankDate, endTime)) {
            return;
        }

        //排行榜最后一天榜单数据
        List<EcologyPoolCommunityServiceRank> ecologyPoolCommunityServiceRanks = ecologyPoolCommunityServiceRankDao.waitAutoSettleList(ecologyPoolCommunityServiceRankConf.getId(), maxRankDate.getRankDate());
        if (CollectionUtil.isEmpty(ecologyPoolCommunityServiceRanks)) {
            return;
        }

        //region 各个排名的奖励
        Map<Long, BigDecimal> prizeMap = new HashMap<>();
        Map<Long, EcologyPoolPrize> ecologyPoolPrizeMap = ecologyPoolPrizeList.stream().collect(Collectors.toMap(EcologyPoolPrize::getBindId, Function.identity()));
        ecologyPoolCommunityServiceRankIncomeConfList.forEach(incomeConf -> {
            EcologyPoolPrize ecologyPoolPrize = ecologyPoolPrizeMap.get(incomeConf.getId());
            if (Objects.nonNull(ecologyPoolPrize)) {
                for (int i = incomeConf.getStartRank() + 1; i <= incomeConf.getEndRank(); i++) {
                    prizeMap.put((long) i, ecologyPoolPrize.getLinkCount());
                }
            }
        });
        //endregion

        //已结算
        ecologyPoolCommunityServiceRankConf.setSettled(true);
        ecologyPoolCommunityServiceRankConf.updateById();

        //总收益奖励
        EcologyPoolPrize totalEcologyPoolPrize = ecologyPoolPrizeDao.getPrizeById(ecologyPoolCommunityServiceRankConf.getId(), EcologyPoolPrizeBindTypeEnum.COMMUNITY_SERVICE_CENTER_RANK, EcologyPoolLinkTypeEnum.POINTS);
        BigDecimal totalPrize = Objects.nonNull(totalEcologyPoolPrize) ? totalEcologyPoolPrize.getLinkCount() : BigDecimal.ZERO;
        //将奖励分配给各个社区网点/服务中心主理人账号
        for (EcologyPoolCommunityServiceRank ecologyPoolCommunityServiceRank : ecologyPoolCommunityServiceRanks) {
            Long sort = ecologyPoolCommunityServiceRank.getSort();
            BigDecimal prize = prizeMap.get(sort);
            if (Objects.nonNull(prize) && prize.compareTo(BigDecimal.ZERO) > 0) {
                //region 分配积分，奖励积分到社区网点/服务中心主理人账号
                EcologyPoolIncreasePointsDTO ecologyPoolIncreasePointsDTO = EcologyPoolIncreasePointsDTO.builder()
                        .linkCount(prize)
                        .linkType(EcologyPoolLinkTypeEnum.POINTS)
                        .poolType(EcologyPoolTypeEnum.ACCOUNT)
                        .daoId(ecologyPoolCommunityServiceRank.getDaoId())
                        .userId(ecologyPoolCommunityServiceRank.getUserId())
                        .operationType(EcologyPoolOperationTypeEnum.PLUS)
                        .sourcePoolType(Objects.equals(ecologyPoolCommunityServiceRankConf.getRankType(), EcologyPoolCommunityServiceRankTypeEnum.COMMUNITY) ? EcologyPoolTypeEnum.COMMUNITY_NETWORK_RANK : EcologyPoolTypeEnum.SERVICE_CENTER_RANK)
                        .sourceDaoId(ecologyPoolCommunityServiceRankConf.getDaoId())
                        .sourceRelationId(ecologyPoolCommunityServiceRankConf.getId())
                        .transactionUuid(IdUtil.simpleUUID())
                        .activeOperatorName("排行榜")
                        .passiveOperatorName("个人生态池")
                        .build();
                ecologyPoolService.increasePoints(ecologyPoolIncreasePointsDTO);
                //endregion
                if (totalPrize.compareTo(BigDecimal.ZERO) > 0) {
                    totalPrize = totalPrize.subtract(prize);
                }
            }
        }
        //将剩余积分回流生态池
        if (totalPrize.compareTo(BigDecimal.ZERO) > 0) {
            //region 回流剩余积分
            EcologyPoolIncreasePointsDTO ecologyPoolIncreasePointsDTO = EcologyPoolIncreasePointsDTO.builder()
                    .linkCount(totalPrize)
                    .linkType(EcologyPoolLinkTypeEnum.POINTS)
                    .poolType(EcologyPoolTypeEnum.BRAND)
                    .daoId(ecologyPoolCommunityServiceRankConf.getDaoId())
                    .operationType(EcologyPoolOperationTypeEnum.BACK_FLOW)
                    .sourcePoolType(Objects.equals(ecologyPoolCommunityServiceRankConf.getRankType(), EcologyPoolCommunityServiceRankTypeEnum.COMMUNITY) ? EcologyPoolTypeEnum.COMMUNITY_NETWORK_RANK : EcologyPoolTypeEnum.SERVICE_CENTER_RANK)
                    .sourceDaoId(ecologyPoolCommunityServiceRankConf.getDaoId())
                    .sourceRelationId(ecologyPoolCommunityServiceRankConf.getId())
                    .transactionUuid(IdUtil.simpleUUID())
                    .activeOperatorName("排行榜")
                    .passiveOperatorName("品牌生态池")
                    .build();
            ecologyPoolService.increasePoints(ecologyPoolIncreasePointsDTO);
            //endregion
        }
    }

    /**
     * 城市服务中心榜单
     *
     * @param list
     * @param ecologyPoolCommunityServiceRankConf
     */
    private void serviceCenter(List<EcologyPoolCommunityServiceRank> list, EcologyPoolCommunityServiceRankConf ecologyPoolCommunityServiceRankConf, List<Long> collectionIdList) {
        // 获取所有的城市服务中心
        List<UserCityServerCentre> userCityServerCentres = userCityServerCentreDao.list();
        if (CollUtil.isEmpty(userCityServerCentres)) {
            return;
        }
        for (UserCityServerCentre userCityServerCentre : userCityServerCentres) {
            EcologyPoolCommunityServiceRank ecologyPoolCommunityServiceRank = new EcologyPoolCommunityServiceRank();
            ecologyPoolCommunityServiceRank.setEcologyPoolCommunityServiceRankConfId(ecologyPoolCommunityServiceRankConf.getId());
            ecologyPoolCommunityServiceRank.setRankDate(DateUtil.date());
            ecologyPoolCommunityServiceRank.setRankType(EcologyPoolCommunityServiceRankTypeEnum.COMMUNITY);
            ecologyPoolCommunityServiceRank.setDaoId(ecologyPoolCommunityServiceRankConf.getDaoId());
            ecologyPoolCommunityServiceRank.setUserId(userCityServerCentre.getUserId());
            ecologyPoolCommunityServiceRank.setRankName(StrUtil.format("{}{}{}", userCityServerCentre.getProvince(), userCityServerCentre.getCity(), userCityServerCentre.getDistrict()));
            ecologyPoolCommunityServiceRank.setHasSort(Boolean.FALSE);
            ecologyPoolCommunityServiceRank.setSort(0L);
            ecologyPoolCommunityServiceRank.setSortChange(0);
            ecologyPoolCommunityServiceRank.setShowStatus(Boolean.FALSE);
            ecologyPoolCommunityServiceRank.setPrizeRatio(0);
            // 获取活动期间内新增的用户数
            Integer userCityServerExcludeExchequerSize = userCityServerCentreDao.getUserCityServerExcludeExchequerList(userCityServerCentre.getUserId(), ecologyPoolCommunityServiceRankConf.getStartTime(), ecologyPoolCommunityServiceRankConf.getEndTime());
            // 获取活动期间内新增的熔炼值
            ecologyPoolCommunityServiceRank.setNewUserCount(userCityServerExcludeExchequerSize);
            // 获取活动期间内新增的熔炼值
            BigDecimal userCityServerExcludeExchequerBigdecimal = userEcologyHatchRecordsDao.getUserCityServerExcludeExchequerList(userCityServerCentre.getUserId(), ecologyPoolCommunityServiceRankConf.getStartTime(), ecologyPoolCommunityServiceRankConf.getEndTime(), collectionIdList);
            ecologyPoolCommunityServiceRank.setNewEcologySmelting(userCityServerExcludeExchequerBigdecimal);
            list.add(ecologyPoolCommunityServiceRank);
        }
    }

    /**
     * 社区网点榜单
     *
     * @param list
     * @param ecologyPoolCommunityServiceRankConf
     */
    private void community(List<EcologyPoolCommunityServiceRank> list, EcologyPoolCommunityServiceRankConf ecologyPoolCommunityServiceRankConf, List<Long> collectionIdList) {
        // 获取所有的城市服务中心,把所有的城市服务中心的数据全都循环操作.让后查询时间内的新增用户数和新增熔炼值.
        List<UserWorkRoom> userWorkRooms = userWorkRoomDao.list();
        if (CollUtil.isEmpty(userWorkRooms)) {
            return;
        }

        // 循环处理所有的数据,获取活动期间内新增的用户数和活动期间内所属社区网点的用户所在生态熔炼内新增的熔炼值写入到list里面
        for (UserWorkRoom userWorkRoom : userWorkRooms) {
            // 根据每一个社区网点,查询活动区间内的新增用户数和新增熔炼值,组装成对象
            EcologyPoolCommunityServiceRank ecologyPoolCommunityServiceRank = new EcologyPoolCommunityServiceRank();
            ecologyPoolCommunityServiceRank.setEcologyPoolCommunityServiceRankConfId(ecologyPoolCommunityServiceRankConf.getId());
            ecologyPoolCommunityServiceRank.setRankDate(DateUtil.date());
            ecologyPoolCommunityServiceRank.setRankType(EcologyPoolCommunityServiceRankTypeEnum.COMMUNITY);
            ecologyPoolCommunityServiceRank.setDaoId(ecologyPoolCommunityServiceRankConf.getDaoId());
            ecologyPoolCommunityServiceRank.setUserId(userWorkRoom.getUserId());
            ecologyPoolCommunityServiceRank.setRankName(userWorkRoom.getWorkName());
            ecologyPoolCommunityServiceRank.setHasSort(Boolean.FALSE);
            ecologyPoolCommunityServiceRank.setSort(0L);
            ecologyPoolCommunityServiceRank.setSortChange(0);
            ecologyPoolCommunityServiceRank.setShowStatus(Boolean.FALSE);
            ecologyPoolCommunityServiceRank.setPrizeRatio(0);
            // 获取活动期间内新增的用户数
            Integer userWorkRoomExcludeExchequerList = userWorkRoomDao.getUserWorkRoomExcludeExchequerList(userWorkRoom.getUserId(), ecologyPoolCommunityServiceRankConf.getStartTime(), ecologyPoolCommunityServiceRankConf.getEndTime());
            // 获取活动期间内新增的熔炼值
            ecologyPoolCommunityServiceRank.setNewUserCount(userWorkRoomExcludeExchequerList);
            // 获取活动期间内新增的熔炼值
            BigDecimal userWorkRoomExcludeExchequerBigDecimal = userEcologyHatchRecordsDao.getUserWorkRoomExcludeExchequerList(userWorkRoom.getUserId(), ecologyPoolCommunityServiceRankConf.getStartTime(), ecologyPoolCommunityServiceRankConf.getEndTime(), collectionIdList);
            ecologyPoolCommunityServiceRank.setNewEcologySmelting(userWorkRoomExcludeExchequerBigDecimal);
            list.add(ecologyPoolCommunityServiceRank);
        }

    }

}




